package com.mulong.mall.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mulong.mall.constants.Constants;
import com.mulong.mall.domain.bo.ProductInventory;
import com.mulong.mall.domain.bo.distributor.*;
import com.mulong.mall.domain.param.distributor.*;
import com.mulong.mall.domain.result.distributor.*;
import com.mulong.mall.service.DistributorDistributionService;
import com.mulong.mall.service.support.DistributorDistributionSupport;
import com.mulong.mall.util.MallRequestContext;

import cn.hutool.core.date.DateUtil;

import com.mulong.common.dao.mall.ChannelDao;
import com.mulong.common.dao.mall.CustomerOrderDao;
import com.mulong.common.dao.mall.DeliveryDao;
import com.mulong.common.dao.mall.ProductDao;
import com.mulong.common.dao.mall.mapper.GoodsDemandMapper;
import com.mulong.common.dao.mall.mapper.MyFavoriteMapper;
import com.mulong.common.domain.pojo.mall.CustomerOrderDetail;
import com.mulong.common.domain.pojo.mall.MyFavorite;
import com.mulong.common.domain.pojo.mall.custom.CustomSupplierChannelDeliveryCharge;
import com.mulong.common.domain.pojo.mall.custom.CustomSupplierChannelDiscount;
import com.mulong.common.domain.pojo.mall.custom.CustomerOrderDetailInfo;
import com.mulong.common.domain.pojo.mall.custom.CustomerOrderDetailInfoQuery;
import com.mulong.common.domain.pojo.mall.custom.DistributionMyFavoriteQuery;
import com.mulong.common.domain.pojo.mall.custom.GoodsDemandQuery;
import com.mulong.common.domain.pojo.mall.custom.ProductInventoryProduct;
import com.mulong.common.domain.pojo.mall.custom.SupplierChannelDeliveryChargeQuery;
import com.mulong.common.domain.pojo.mall.custom.SupplierChannelDiscountQuery;
import com.mulong.common.enums.CustomerOrderStatus;
import com.mulong.common.enums.GoodsDemandStatus;
import com.mulong.common.exception.ErrorEnums;
import com.mulong.common.exception.MulongException;
import com.mulong.common.manager.FinanceManager;
import com.mulong.common.manager.IdManager;
import com.mulong.common.util.MulongUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * DistributionServiceImpl
 * 
 * @author mulong
 * @data 2021-05-29 21:35:01
 */
@Slf4j
@Service
public class DistributorDistributionServiceImpl implements DistributorDistributionService {
    @Autowired
    private ProductDao productDao;
    @Autowired
    private CustomerOrderDao customerOrderDao;
    @Autowired
    private ChannelDao channelDao;
    @Autowired
    private DeliveryDao deliveryDao;
    @Autowired
    private GoodsDemandMapper goodsDemandMapper;
    @Autowired
    private MyFavoriteMapper myFavoriteMapper;
    @Autowired
    private DistributorDistributionSupport distributorDistributionSupport;
    @Autowired
    private IdManager idManager;
    @Autowired
    private FinanceManager financeManager;

    /**
     * 查询商品库存
     * 
     * @author mulong 
     */
    public DistributionProductInventoryResult getProductInventory(DistributionProductInventoryParam param) {
        String skuPrefix = param.getSkuPrefix();
        if (StringUtils.isBlank(skuPrefix) || skuPrefix.length() < 4) {
            throw new MulongException(ErrorEnums.ILLEGAL_FORMAT_PARAM_TEMPLETE.format("skuPrefix"));
        }
        List<ProductInventoryProduct> records = productDao.queryProductInventoryProductBySkuPrefix(skuPrefix);
        DistributionProductInventoryResult distributionProductInventoryResult = new DistributionProductInventoryResult();
        if (!CollectionUtils.isEmpty(records)) {
            List<ProductInventory> list = records.stream().map(ProductInventory::new).collect(Collectors.toList());
            distributionProductInventoryResult.setList(list);   
        }
        return distributionProductInventoryResult;
    }

    /**
     * 下单
     * 
     * @author mulong 
     */
    @Override
    public DistributionBookingResult booking(DistributionBookingParam param) {
        if (CollectionUtils.isEmpty(param.getDetails())) {
            throw new MulongException(ErrorEnums.BOOKING_FAILED_TEMPLETE.format("没有商品信息"));
        }
        BigDecimal needPayPrice = BigDecimal.ZERO;
        String name = param.getName();
        String mobilephone = param.getMobilephone();
        String telephone = param.getTelephone();
        String province = param.getProvince();
        String city = param.getCity();
        String district = param.getDistrict();
        String zipcode = param.getZipcode();
        String customizedOrderId = param.getCustomizedOrderId();
        String address = param.getAddress();
        String remark = param.getRemark();
        List<CustomerOrderDetail> records = new ArrayList<>();
        for (DistributionBookingParam.Detail detail : param.getDetails()) {
            int qty = detail.getQty();
            BigDecimal priceTotal = detail.getPriceTotal();
            BigDecimal pricePreEach = detail.getPricePreEach();
            BigDecimal deliveryChargePreEach = detail.getDeliveryChargePreEach();
            String sku = detail.getSku();
            Integer supplierChannelId = detail.getSupplierChannelId();
            String normalizedSize = detail.getNormalizedSize();
            Long supplierChannelDeliveryChargeId = detail.getSupplierChannelDeliveryChargeId();
            for(;;) {
                if (qty == 0) {
                    break;
                }
                String orderId = idManager.nextCustomerOrderId();
                CustomerOrderDetail record = new CustomerOrderDetail();
                record.setOrderId(orderId);
                record.setGatewayAccountId(MallRequestContext.getGatewayAccountId());
                record.setCustomizedOrderId(customizedOrderId);
                record.setSku(sku);
                record.setSupplierChannelId(supplierChannelId);
                record.setNormalizedSize(normalizedSize);
                record.setMarketPrice(detail.getMarketPrice());
                record.setDiscountPrice(detail.getDiscountPrice());
                record.setDeliveryCharge(deliveryChargePreEach);
                record.setPayPrice(detail.getPricePreEach());
                record.setActualDeliveryCharge(BigDecimal.ZERO);
                record.setQty(1);
                record.setReceiverName(name);
                record.setReceiverProvince(province);
                record.setReceiverCity(city);
                record.setReceiverDistrict(district);
                record.setReceiverAddress(address);
                record.setExpectDeliveryTypeId(3);
                record.setStatus(CustomerOrderStatus.ARREARAGE.getCode());
                record.setCreateTime(new Date());
                record.setRemark(remark);
                records.add(record);
                needPayPrice = needPayPrice.add(pricePreEach).add(deliveryChargePreEach);
                qty -= 1;
            }
        }
        customerOrderDao.addCustomerOrderDetail(records);
        DistributionBookingResult distributionBookingResult = new DistributionBookingResult();
        distributionBookingResult.setNeedPayPrice(needPayPrice);
        return distributionBookingResult;
    }

    /**
     * @author mulong 
     */
    @Override
    public GetDistributionGrouponByPageResult getGrouponByPage(GetDistributionGrouponByPageParam param) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionGroupon getGrouponById(Long id) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 订单列表
     * 
     * @author mulong 
     */
    @Override
    public GetDistributionOrderByPageResult getOrderByPage(GetDistributionOrderByPageParam param) {
        CustomerOrderDetailInfoQuery query = new CustomerOrderDetailInfoQuery();
        query.setGatewayAccountId(MallRequestContext.getGatewayAccountId());
        query.setCustomizedOrderId(param.getCustomizedOrderId());
        query.setSku(param.getSku());
        query.setSupplierChannelId(param.getSupplierChannelId());
        query.setReceiverName(param.getReceiverName());
        query.setExpressNo(param.getExpressNo());
        query.setStatus(param.getStatus());
        if (StringUtils.isNotBlank(param.getCreateTimeBegin())) {
            query.setCreateTimeBegin(DateUtil.parse(param.getCreateTimeBegin(), "yyyy-MM-dd"));
        }
        if (StringUtils.isNotBlank(param.getCreateTimeEnd())) {
            query.setCreateTimeEnd(DateUtil.parse(param.getCreateTimeEnd(), "yyyy-MM-dd"));
        }
        if (StringUtils.isNotBlank(param.getFeedbackTimeBegin())) {
            query.setFeedbackTimeBegin(DateUtil.parse(param.getFeedbackTimeBegin(), "yyyy-MM-dd"));
        }
        if (StringUtils.isNotBlank(param.getFeedbackTimeEnd())) {
            query.setFeedbackTimeEnd(DateUtil.parse(param.getFeedbackTimeEnd(), "yyyy-MM-dd"));
        }
        query.setOrderBy("cod.`create_time` DESC");
        int pageNo = param.getPageNo() == null ? Constants.DEFAULT_PAGE_NO : param.getPageNo();
        int pageSize = param.getPageSize() == null ? Constants.DEFAULT_PAGE_SIZE : param.getPageSize();
        PageHelper.startPage(pageNo, pageSize, true);
        Page<CustomerOrderDetailInfo> page = (Page<CustomerOrderDetailInfo>) customerOrderDao.queryCustomerOrderDetailInfo(query);
        GetDistributionOrderByPageResult getDistributionOrderByPageResult = new GetDistributionOrderByPageResult(page.getPageNum(), page.getPageSize(), (int)page.getTotal());
        List<CustomerOrderDetailInfo> list = page.getResult();
        if (!CollectionUtils.isEmpty(list)) {
            getDistributionOrderByPageResult.setResult(list.stream().map(DistributionOrder::new).collect(Collectors.toList()));
        }
        return getDistributionOrderByPageResult;
    }

    /**
     * 下载订单
     * 
     * @author mulong 
     */
    @Override
    public ResponseEntity<byte[]> downloadOrder(DownloadOrderParam param) {
        String fileName = "订单.xls";
        // get data
        CustomerOrderDetailInfoQuery query = new CustomerOrderDetailInfoQuery();
        query.setGatewayAccountId(MallRequestContext.getGatewayAccountId());
        query.setCustomizedOrderId(param.getCustomizedOrderId());
        query.setSku(param.getSku());
        query.setSupplierChannelId(param.getSupplierChannelId());
        query.setReceiverName(param.getReceiverName());
        query.setExpressNo(param.getExpressNo());
        query.setStatus(param.getStatus());
        if (StringUtils.isNotBlank(param.getCreateTimeBegin())) {
            query.setCreateTimeBegin(DateUtil.parse(param.getCreateTimeBegin(), "yyyy-MM-dd"));
        }
        if (StringUtils.isNotBlank(param.getCreateTimeEnd())) {
            query.setCreateTimeEnd(DateUtil.parse(param.getCreateTimeEnd(), "yyyy-MM-dd"));
        }
        if (StringUtils.isNotBlank(param.getFeedbackTimeBegin())) {
            query.setFeedbackTimeBegin(DateUtil.parse(param.getFeedbackTimeBegin(), "yyyy-MM-dd"));
        }
        if (StringUtils.isNotBlank(param.getFeedbackTimeEnd())) {
            query.setFeedbackTimeEnd(DateUtil.parse(param.getFeedbackTimeEnd(), "yyyy-MM-dd"));
        }
        query.setOrderBy("cod.`create_time` DESC");
        List<CustomerOrderDetailInfo> records = customerOrderDao.queryCustomerOrderDetailInfo(query);
        // build content
        byte[] content = null;
        try (HSSFWorkbook workbook = new HSSFWorkbook()) {
            HSSFSheet sheet = workbook.createSheet(Constants.DISTRIBUTOR_DOWNLOAD_ORDER_SHEET_NAME);            
            List<String> titles = Constants.DISTRIBUTOR_DOWNLOAD_ORDER_SHEET_TITLE;
            MulongUtil.addTitle(workbook, sheet, titles);
            HSSFCellStyle defaultStyle = MulongUtil.getDefaultCellStyle(workbook);
            int lastRowNum = sheet.getLastRowNum();
            for (int j = 0; j < records.size(); j++) {
                CustomerOrderDetailInfo record = records.get(j);
                HSSFRow row = sheet.createRow(j + (lastRowNum + 1));
                distributorDistributionSupport.addRow(row, record, defaultStyle);
            }
            content = MulongUtil.toByteArray(workbook);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            content = null;
        }
        if (content == null) {
            throw new MulongException(ErrorEnums.HANDLE_FAILED_TEMPLETE.format("导出数据异常"));
        }
        // build response
        return MulongUtil.buildDownloadResponse("application/octet-stream", fileName, content);
    }

    /**
     * 付款全部未付款订单
     * 
     * @author mulong 
     */
    @Override
    public DistributionPayAllOrderResult payAllOrder() {
        int payOrderCount = 0;
        BigDecimal totalPay = BigDecimal.ZERO;
        CustomerOrderDetailInfoQuery query = new CustomerOrderDetailInfoQuery();
        query.setGatewayAccountId(MallRequestContext.getGatewayAccountId());
        query.setStatus(CustomerOrderStatus.ARREARAGE.getCode());
        query.setOrderBy("cod.`create_time` ASC");
        List<CustomerOrderDetailInfo> needPayRecords = customerOrderDao.queryCustomerOrderDetailInfo(query);
        if (!CollectionUtils.isEmpty(needPayRecords)) {
            List<CustomerOrderDetail> orders = new ArrayList<>(needPayRecords.size());
            for (CustomerOrderDetailInfo record : needPayRecords) {
                String orderId = record.getOrderId();
                BigDecimal payPrice = record.getPayPrice();
                log.info("orderId [{}] paid [{}]", orderId, payPrice);
                payOrderCount += 1;
                totalPay = totalPay.add(payPrice);
                orders.add(record);
            }
            log.info("payOrderCount [{}] totalPay [{}]", payOrderCount, totalPay);
            try {
                financeManager.payCustomerOrder(orders);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new MulongException(ErrorEnums.ORDER_PAY_FAILED);
            }
            log.info("pay complete");
        }
        DistributionPayAllOrderResult distributionPayAllOrderResult = new DistributionPayAllOrderResult();
        distributionPayAllOrderResult.setPayOrderCount(payOrderCount);
        distributionPayAllOrderResult.setTotalPay(totalPay);
        return distributionPayAllOrderResult;
    }

    /**
     * 付款选中订单
     * 
     * @author mulong 
     */
    @Override
    public DistributionPaySelectedOrderResult paySelectedOrder(DistributionPaySelectedOrderParam param) {
        int payOrderCount = 0;
        BigDecimal totalPay = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(param.getDetails())) {
            List<CustomerOrderDetail> orders = new ArrayList<>();
            for (DistributionPaySelectedOrderParam.Detail detail : param.getDetails()) {
                String orderId = detail.getOrderId();
                BigDecimal payPrice = detail.getPayPrice();
                CustomerOrderDetail customerOrderDetail = customerOrderDao.queryCustomerOrderDetailByOrderId(orderId);
                if (customerOrderDetail == null 
                        || !CustomerOrderStatus.ARREARAGE.getCode().equals(customerOrderDetail.getStatus())
                        || !customerOrderDetail.getPayPrice().equals(payPrice)) {
                    throw new MulongException(ErrorEnums.ORDER_PAY_FAILED_TEMPLETE.format("订单"+orderId+"状态异常"));
                }
                orders.add(customerOrderDetail);
            }
            for (CustomerOrderDetail order : orders) {
                String orderId = order.getOrderId();
                BigDecimal payPrice = order.getPayPrice();
                log.info("orderId [{}] paid [{}]", orderId, payPrice);
                payOrderCount += 1;
                totalPay = totalPay.add(payPrice);
            }
            log.info("payOrderCount [{}] totalPay [{}]", payOrderCount, totalPay);
            try {
                financeManager.payCustomerOrder(orders);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new MulongException(ErrorEnums.ORDER_PAY_FAILED);
            }
            log.info("pay complete");
        }
        DistributionPaySelectedOrderResult distributionPaySelectedOrderResult = new DistributionPaySelectedOrderResult();
        distributionPaySelectedOrderResult.setPayOrderCount(payOrderCount);
        distributionPaySelectedOrderResult.setTotalPay(totalPay);
        return distributionPaySelectedOrderResult;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionOrder getOrderById(Long id) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionOrder putOrderById(Long id, DistributionOrder order) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @author mulong 
     */
    @Override
    public GetDistributionTradeByPageResult getTradeByPage(GetDistributionTradeByPageParam param) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionTrade getTradeById(Long id) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionTrade putTradeById(Long id, DistributionTrade trade) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @author mulong 
     */
    @Override
    public GetDistributionDiscountByPageResult getDiscountByPage(GetDistributionDiscountByPageParam param) {
        SupplierChannelDiscountQuery query = new SupplierChannelDiscountQuery();
        query.setChannelId(param.getChannelId());
        query.setBrandId(param.getBrandId());
        query.setGoodsCategory(param.getGoodsCategory());
        query.setOrderBy("scd.`update_time` DESC");
        int pageNo = param.getPageNo() == null ? Constants.DEFAULT_PAGE_NO : param.getPageNo();
        int pageSize = param.getPageSize() == null ? Constants.DEFAULT_PAGE_SIZE : param.getPageSize();
        PageHelper.startPage(pageNo, pageSize, true);
        Page<CustomSupplierChannelDiscount> page = (Page<CustomSupplierChannelDiscount>) channelDao.queryDiscount(query);
        GetDistributionDiscountByPageResult getDistributionDiscountByPageResult = new GetDistributionDiscountByPageResult(page.getPageNum(), page.getPageSize(), (int)page.getTotal());
        List<CustomSupplierChannelDiscount> list = page.getResult();
        if (!CollectionUtils.isEmpty(list)) {
            getDistributionDiscountByPageResult.setResult(list.stream().map(DistributionDiscount::new).collect(Collectors.toList()));
        }
        return getDistributionDiscountByPageResult;
    }

    /**
     * @author mulong 
     */
    @Override
    public GetDistributionDeliveryChargeByPageResult getDeliveryChargeByPage(
            GetDistributionDeliveryChargeByPageParam param) {
        SupplierChannelDeliveryChargeQuery query = new SupplierChannelDeliveryChargeQuery();
        query.setDeliveryTypeId(param.getDeliveryTypeId());
        query.setProvince(param.getProvince());
        query.setOrderBy("scdc.`update_time` DESC");
        int pageNo = param.getPageNo() == null ? Constants.DEFAULT_PAGE_NO : param.getPageNo();
        int pageSize = param.getPageSize() == null ? Constants.DEFAULT_PAGE_SIZE : param.getPageSize();
        PageHelper.startPage(pageNo, pageSize, true);
        Page<CustomSupplierChannelDeliveryCharge> page = (Page<CustomSupplierChannelDeliveryCharge>) deliveryDao.queryDeliveryCharge(query);
        GetDistributionDeliveryChargeByPageResult getDistributionExpressChargeByPageResult = new GetDistributionDeliveryChargeByPageResult(page.getPageNum(), page.getPageSize(), (int)page.getTotal());
        List<CustomSupplierChannelDeliveryCharge> list = page.getResult();
        if (!CollectionUtils.isEmpty(list)) {
            getDistributionExpressChargeByPageResult.setResult(list.stream().map(DistributionDeliveryCharge::new).collect(Collectors.toList()));
        }
        return getDistributionExpressChargeByPageResult;
    }

    /**
     * @author mulong 
     */
    @Override
    public GetDistributionGoodsDemandByPageResult getGoodsDemandByPage(GetDistributionGoodsDemandByPageParam param) {
        GoodsDemandQuery query = new GoodsDemandQuery();
        query.setArtNo(param.getArtNo());
        query.setStatus(param.getStatus());
        query.setNeedNotice(param.getNeedNotice());
        query.setOrderBy("`create_time` DESC");
        int pageNo = param.getPageNo() == null ? Constants.DEFAULT_PAGE_NO : param.getPageNo();
        int pageSize = param.getPageSize() == null ? Constants.DEFAULT_PAGE_SIZE : param.getPageSize();
        PageHelper.startPage(pageNo, pageSize, true);
        Page<com.mulong.common.domain.pojo.mall.GoodsDemand> page = 
                (Page<com.mulong.common.domain.pojo.mall.GoodsDemand>) goodsDemandMapper.selectByParam(query);
        GetDistributionGoodsDemandByPageResult getDistributionGoodsDemandByPageResult = 
                new GetDistributionGoodsDemandByPageResult(page.getPageNum(), page.getPageSize(), (int)page.getTotal());
        List<com.mulong.common.domain.pojo.mall.GoodsDemand> list = page.getResult();
        if (!CollectionUtils.isEmpty(list)) {
            getDistributionGoodsDemandByPageResult.setResult(list.stream().map(DistributionGoodsDemand::new).collect(Collectors.toList()));
        }
        return getDistributionGoodsDemandByPageResult;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionGoodsDemand addGoodsDemand(DistributionGoodsDemand goodsDemand) {
        Integer gatewayAccountId = MallRequestContext.getGatewayAccountId();
        if (gatewayAccountId == null) {
            throw new MulongException(ErrorEnums.ILLEGAL_REQUEST);
        }
        goodsDemand.setId(null);
        com.mulong.common.domain.pojo.mall.GoodsDemand newRecord = goodsDemand.buildGoodsDemand();
        Date now = new Date();
        newRecord.setApplyGatewayAccountId(gatewayAccountId);
        newRecord.setStatus(GoodsDemandStatus.WAITING.getCode());
        newRecord.setCreateTime(now);
        newRecord.setUpdateTime(now);
        goodsDemandMapper.insertUseGeneratedKeys(newRecord);
        return new DistributionGoodsDemand(newRecord);
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionGoodsDemand getGoodsDemandById(Long id) {
        com.mulong.common.domain.pojo.mall.GoodsDemand record = goodsDemandMapper.selectById(id);
        if (record == null) {
            throw new MulongException(ErrorEnums.RESOURCE_NOT_EXISTS);
        }
        return new DistributionGoodsDemand(record);
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionGoodsDemand putGoodsDemandById(Long id, DistributionGoodsDemand goodsDemand) {
        if (!id.equals(goodsDemand.getId())) {
            log.error("id mismatch");
            throw new MulongException(ErrorEnums.ILLEGAL_PARAM);
        }
        com.mulong.common.domain.pojo.mall.GoodsDemand record = goodsDemandMapper.selectById(id);
        if (record == null) {
            throw new MulongException(ErrorEnums.RESOURCE_NOT_EXISTS);
        }
        com.mulong.common.domain.pojo.mall.GoodsDemand newRecord = goodsDemand.buildGoodsDemand();
        record.setStatus(newRecord.getStatus());
        record.setRemark(newRecord.getRemark());
        record.setUpdateTime(new Date());
        goodsDemandMapper.updateByPrimaryKey(record);
        return new DistributionGoodsDemand(record);
    }

    /**
     * @author mulong 
     */
    @Override
    public GetDistributionMyFavoriteByPageResult getMyFavoriteByPage(GetDistributionMyFavoriteByPageParam param) {
        Integer gatewayAccountId = MallRequestContext.getGatewayAccountId();
        if (gatewayAccountId == null) {
            throw new MulongException(ErrorEnums.ILLEGAL_REQUEST);
        }
        DistributionMyFavoriteQuery query = new DistributionMyFavoriteQuery();
        query.setGatewayAccountId(gatewayAccountId);
        query.setArtNo(param.getArtNo());
        query.setProductName(param.getProductName());
        query.setOrderBy("mf.`create_time` DESC");
        int pageNo = param.getPageNo() == null ? Constants.DEFAULT_PAGE_NO : param.getPageNo();
        int pageSize = param.getPageSize() == null ? Constants.DEFAULT_PAGE_SIZE : param.getPageSize();
        PageHelper.startPage(pageNo, pageSize, true);
        Page<com.mulong.common.domain.pojo.mall.custom.DistributionMyFavorite> page = 
                (Page<com.mulong.common.domain.pojo.mall.custom.DistributionMyFavorite>) myFavoriteMapper.selectDistributionMyFavoriteByParam(query);
        GetDistributionMyFavoriteByPageResult getDistributionMyFavoriteByPageResult = 
                new GetDistributionMyFavoriteByPageResult(page.getPageNum(), page.getPageSize(), (int)page.getTotal());
        List<com.mulong.common.domain.pojo.mall.custom.DistributionMyFavorite> list = page.getResult();
        if (!CollectionUtils.isEmpty(list)) {
            getDistributionMyFavoriteByPageResult.setResult(list.stream().map(DistributionMyFavorite::new).collect(Collectors.toList()));
        }
        return getDistributionMyFavoriteByPageResult;
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionMyFavorite addMyFavorite(DistributionMyFavorite myFavorite) {
        Integer gatewayAccountId = MallRequestContext.getGatewayAccountId();
        if (gatewayAccountId == null) {
            throw new MulongException(ErrorEnums.ILLEGAL_REQUEST);
        }
        myFavorite.setId(null);
        myFavorite.setProductName(null);
        myFavorite.setImgUrl(null);
        com.mulong.common.domain.pojo.mall.MyFavorite newRecord = myFavorite.buildMyFavorite();
        Date now = new Date();
        newRecord.setGatewayAccountId(gatewayAccountId);
        newRecord.setCreateTime(now);
        newRecord.setUpdateTime(now);
        myFavoriteMapper.insertUseGeneratedKeys(newRecord);
        return new DistributionMyFavorite(newRecord);
    }

    /**
     * @author mulong 
     */
    @Override
    public DistributionMyFavorite deleteMyFavoriteById(Long id) {
        MyFavorite record = myFavoriteMapper.selectById(id);
        if (record == null) {
            throw new MulongException(ErrorEnums.RESOURCE_NOT_EXISTS);
        }
        Integer gatewayAccountId = MallRequestContext.getGatewayAccountId();
        if (gatewayAccountId == null) {
            throw new MulongException(ErrorEnums.ILLEGAL_REQUEST);
        }
        if (!gatewayAccountId.equals(record.getGatewayAccountId())) {
            throw new MulongException(ErrorEnums.RESOURCE_NOT_EXISTS);
        }
        myFavoriteMapper.deleteById(id);
        return new DistributionMyFavorite(record);
    }

}
